package com.ssyx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ssyx.constant.GlobalConstant;
import com.ssyx.constant.RabbitMQConstant;
import com.ssyx.constant.RedisConstant;
import com.ssyx.exception.SsyxException;
import com.ssyx.mapper.SkuInfoMapper;
import com.ssyx.model.product.SkuAttrValue;
import com.ssyx.model.product.SkuImage;
import com.ssyx.model.product.SkuInfo;
import com.ssyx.model.product.SkuPoster;
import com.ssyx.result.ResultCodeEnum;
import com.ssyx.service.*;
import com.ssyx.vo.product.SkuInfoQueryVo;
import com.ssyx.vo.product.SkuInfoVo;
import com.ssyx.vo.product.SkuStockLockVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.IntStream;

/**
 * @program: ssyx-parent
 * @className: SkuInfoServiceImpl
 * @description: 类
 * @data: 2024/3/11 16:14
 * @author: ihu
 * @version: 1.0
 **/

@Slf4j
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo>
		implements SkuInfoService {
	
	@Resource
	private SkuPosterService skuPosterService;
	@Resource
	private SkuImageService skuImagesService;
	@Resource
	private SkuAttrValueService skuAttrValueService;
	@Resource
	private RabbitMQService rabbitMQService;
	@Resource
	private SkuInfoMapper skuInfoMapper;
	//	@Resource
//	private RedissonClient redissonClient;
	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	/**
	 * 获取sku分页列表
	 */
	@Override
	public IPage<SkuInfo> selectPage(Page<SkuInfo> pageParam, SkuInfoQueryVo skuInfoQueryVo) {
		//获取条件值
		String keyword = skuInfoQueryVo.getKeyword();
		String skuType = skuInfoQueryVo.getSkuType();
		Long categoryId = skuInfoQueryVo.getCategoryId();
		return baseMapper.selectPage(pageParam, Wrappers.<SkuInfo>lambdaQuery().like(!StringUtils.isEmpty(keyword),
				SkuInfo::getSkuName, keyword).eq(!StringUtils.isEmpty(skuType), SkuInfo::getSkuType, skuType).eq(!StringUtils.isEmpty(categoryId), SkuInfo::getCategoryId, categoryId));
	}
	
	/**
	 * 添加商品
	 */
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public void saveSkuInfo(SkuInfoVo skuInfoVo) {
		List<SkuPoster> skuPosterList = skuInfoVo.getSkuPosterList();
		List<SkuImage> skuImagesList = skuInfoVo.getSkuImagesList();
		List<SkuAttrValue> skuAttrValueList = skuInfoVo.getSkuAttrValueList();
		if (CollectionUtils.isEmpty(skuAttrValueList)) {
			log.error("sku属性不能为空");
			throw new SsyxException(ResultCodeEnum.ILLEGAL_PARAM);
		}
		if (CollectionUtils.isEmpty(skuPosterList)) {
			log.error("sku海报不能为空");
			throw new SsyxException(ResultCodeEnum.ILLEGAL_PARAM);
		}
		if (CollectionUtils.isEmpty(skuImagesList)) {
			log.error("sku图片不能为空");
			throw new SsyxException(ResultCodeEnum.ILLEGAL_PARAM);
		}
		// 保存sku信息
		SkuInfo skuInfo = new SkuInfo();
		BeanUtils.copyProperties(skuInfoVo, skuInfo);
		save(skuInfo);
		
		// 保存sku海报
		skuPosterList.forEach(e -> e.setSkuId(skuInfo.getId()));
		skuPosterService.saveBatch(skuPosterList);
		
		// 保存sku图片
		IntStream.range(GlobalConstant.INTEGER_ZERO, skuImagesList.size())
				.forEach(e -> {
					skuImagesList.get(e).setSkuId(skuInfo.getId());
					skuImagesList.get(e).setSort(e + GlobalConstant.INTEGER_ONE);
				});
		skuImagesService.saveBatch(skuImagesList);
		
		// 保存sku平台属性
		IntStream.range(GlobalConstant.INTEGER_ZERO, skuAttrValueList.size())
				.forEach(e -> {
					skuAttrValueList.get(e).setSkuId(skuInfo.getId());
					skuAttrValueList.get(e).setSort(e + GlobalConstant.INTEGER_ONE);
				});
		skuAttrValueService.saveBatch(skuAttrValueList);
	}
	
	/**
	 * 根据id获取商品信息
	 */
	@Override
	public SkuInfoVo getSkuInfoVo(Long skuId) {
		SkuInfoVo skuInfoVo = new SkuInfoVo();
		SkuInfo skuInfo = getById(skuId);
		BeanUtils.copyProperties(skuInfo, skuInfoVo);
		skuInfoVo.setSkuImagesList(skuImagesService.findBySkuId(skuId));
		skuInfoVo.setSkuPosterList(skuPosterService.findBySkuId(skuId));
		skuInfoVo.setSkuAttrValueList(skuAttrValueService.findBySkuId(skuId));
		return skuInfoVo;
	}
	
	/**
	 * 修改商品
	 */
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public void updateSkuInfo(SkuInfoVo skuInfoVo) {
		Long id = skuInfoVo.getId();
		// 删除sku信息
		removeById(id);
		// 删除sku海报详情
		skuPosterService.remove(new LambdaQueryWrapper<SkuPoster>().eq(SkuPoster::getSkuId, id));
		//删除sku图片
		skuImagesService.remove(new LambdaQueryWrapper<SkuImage>().eq(SkuImage::getSkuId, id));
		//删除sku平台属性
		skuAttrValueService.remove(new LambdaQueryWrapper<SkuAttrValue>().eq(SkuAttrValue::getSkuId, id));
		saveSkuInfo(skuInfoVo);
	}
	
	/**
	 * 商品上架
	 */
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public void publish(Long skuId, Integer status) {
		// 更改发布状态
		if (status.equals(GlobalConstant.INTEGER_ONE)) {
			SkuInfo skuInfoUp = new SkuInfo();
			skuInfoUp.setId(skuId);
			skuInfoUp.setPublishStatus(GlobalConstant.INTEGER_ONE);
			updateById(skuInfoUp);
			// 商品上架 后续会完善：发送mq消息更新es数据
			rabbitMQService.sendMessage(RabbitMQConstant.EXCHANGE_GOODS_DIRECT, RabbitMQConstant.ROUTING_GOODS_UPPER,
					skuId);
		} else {
			SkuInfo skuInfoUp = new SkuInfo();
			skuInfoUp.setId(skuId);
			skuInfoUp.setPublishStatus(GlobalConstant.INTEGER_ZERO);
			updateById(skuInfoUp);
			// 商品下架 后续会完善：发送mq消息更新es数据
			rabbitMQService.sendMessage(RabbitMQConstant.EXCHANGE_GOODS_DIRECT, RabbitMQConstant.ROUTING_GOODS_LOWER,
					skuId);
		}
	}
	
	@Override
	public Boolean checkAndLock(List<SkuStockLockVo> skuStockLockVoList, String orderNo) {
		// 判断skuStockLockVoList集合是否为空
		if (CollectionUtils.isEmpty(skuStockLockVoList)) {
			log.error("库存锁定失败");
			throw new SsyxException(ResultCodeEnum.DATA_ERROR);
		}
		// 遍历skuStockLockVoList得到每个商品，验证库存并锁定库存，具备原子性
//		skuStockLockVoList.forEach(this::checkLock);
//		// 只要有一个商品锁定失败，所有锁定成功的商品都解锁
//		boolean flag = skuStockLockVoList.stream().anyMatch(skuStockLockVo -> !skuStockLockVo.getIsLock());
//		if (flag) {
//			//所有锁定成功的商品都解锁
//			skuStockLockVoList.stream().filter(SkuStockLockVo::getIsLock)
//					.forEach(skuStockLockVo -> skuInfoMapper.unlockStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum
//					()));
//			//返回失败的状态
//			return false;
//		}
//		// 如果所有商品都锁定成功了，redis缓存相关数据，为了方便后面解锁和减库存
//		redisTemplate.opsForValue().set(RedisConstant.SROCK_INFO + orderNo, skuStockLockVoList);
		return true;
	}
	
	@Override
	public List<SkuInfo> findNewPersonSkuInfoList() {
		// 需满足：is_new_person=1 publish_status=1 显示其中三个
		// 获取第一页数据，每页显示三条记录
		Page<SkuInfo> pageParam = new Page<>(GlobalConstant.INTEGER_ONE, GlobalConstant.INTEGER_THREE);
		IPage<SkuInfo> skuInfoPage = baseMapper.selectPage(pageParam,
				Wrappers.<SkuInfo>lambdaQuery().eq(SkuInfo::getIsNewPerson, GlobalConstant.INTEGER_ONE).eq(SkuInfo::getPublishStatus, GlobalConstant.INTEGER_ONE).orderByDesc(SkuInfo::getStock));
		return skuInfoPage.getRecords();
	}
	
	//扣减库存成功，更新订单状态
	@Override
	public void minusStock(String orderNo) {
		//从redis获取锁定库存信息
		List<SkuStockLockVo> skuStockLockVoList =
				(List<SkuStockLockVo>) redisTemplate.opsForValue().get(RedisConstant.SROCK_INFO + orderNo);
		if (CollectionUtils.isEmpty(skuStockLockVoList)) {
			return;
		}
		//遍历集合，得到每个对象，减库存
		skuStockLockVoList.forEach(skuStockLockVo -> {
			skuInfoMapper.minusStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
		});
		//删除redis数据
		redisTemplate.delete(RedisConstant.SROCK_INFO + orderNo);
	}
	
	// 遍历skuStockLockVoList得到每个商品，验证库存并锁定库存，具备原子性
//	private void checkLock(SkuStockLockVo skuStockLockVo) {
//		// 获取公平锁
//		RLock rLock = redissonClient.getFairLock(RedisConstant.SKUKEY_PREFIX + skuStockLockVo.getSkuId());
//		// 加锁
//		rLock.lock();
//		try {
//			//验证库存
//			SkuInfo skuInfo = skuInfoMapper.checkStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
//			//判断没有满足条件商品，设置isLock值false，返回
//			if (skuInfo == null) {
//				skuStockLockVo.setIsLock(false);
//				return;
//			}
//			//有满足条件商品
//			if (skuInfoMapper.lockStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum()).equals(GlobalConstant
//			.INTEGER_ONE)) {
//				skuStockLockVo.setIsLock(true);
//			}
//		} finally {
//			//解锁
//			rLock.unlock();
//		}
//	}
	
}
